<template>
  <div class="banner" v-loading="loading">
    <div class="action-bar">
      <button class="btn btn-rainbow" @click="showAddBanner = true">
        ✨ 添加新轮播图
      </button>
    </div>
    <div class="carousel-grid">
      <div
        class="carousel-card"
        v-for="(item, index) in bannerList"
        :key="index"
      >
        <div
          class="carousel-image"
          :style="{
            backgroundImage: `url(${item.url})`,
            backgroundSize: 'cover',
            backgroundPosition: 'center',
          }"
        ></div>
        <div class="carousel-content">
          <button class="btn btn-danger" @click="delBanner(item)">删除</button>
          <button
            class="btn"
            :class="item.status === 0 ? 'btn-success' : 'btn-disabled'"
            @click="toggleStatus(item.id, item.status)"
          >
            {{ item.status === 0 ? "启用" : "禁用" }}
          </button>
        </div>
      </div>
    </div>

    <!-- 分页 -->
    <el-pagination
      v-show="bannerList.length > 0"
      background
      layout="prev, pager, next"
      :total="total"
      :current-page="page"
      :page-size="pageSize"
      @current-change="handleCurrentChange"
      :page-count="7"
      style="text-align: right; margin-top: 24px"
    >
    </el-pagination>
    <!-- 新增轮播图弹窗 -->
    <el-dialog
      title="新增轮播图"
      :visible.sync="showAddBanner"
      width="60%"
      :close-on-click-modal="false"
      @close="showAddBanner = false"
    >
      <div v-loading="isUpload">
        <input
          type="file"
          @change="handleFileChange"
          multiple
          ref="fileInput"
          style="display: none"
        />
        <div
          class="file-tool"
          @dragover="allowDrop"
          @drop="dropFiles"
          @click="$refs.fileInput.click()"
        >
          <i class="el-icon-upload"></i>
          <span>
            支持拖拽上传或<span style="color: rgb(95, 158, 255)">点击上传</span>
          </span>
          <br />
          <span style="margin-top: -16px; font-size: 10px"
            >只能上传jpg/png/jpeg/gif文件，且不超过2M</span
          >
        </div>
        <div class="file-container">
          <div class="item" v-for="(item, index) in fileList" :key="index">
            <img :src="item.url" alt="" />
            <span class="success">✅</span>
            <span class="error" @click="removeFile(index)">❌</span>
          </div>
        </div>
        <div
          v-show="fileList.length > 0"
          style="text-align: center; margin-top: 20px"
        >
          <el-button type="primary" style="width: 40%" @click="upload">
            开始上传
          </el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { uploadFiles } from "@/api/common/common";
import {
  addBanner,
  getBannerList,
  delBanner,
  updateStatus,
} from "@/api/admin/banner";
import { MessageBox } from "element-ui";
export default {
  name: "BannerView",
  data() {
    return {
      showAddBanner: false,
      fileList: [],
      isUpload: false,
      bannerList: [],
      page: 1,
      pageSize: 8,
      total: 0,
      loading: false,
    };
  },
  created() {
    this.getBannerList();
  },
  methods: {
    // 分页查询轮播图
    async getBannerList() {
      const res = await getBannerList({
        page: this.page,
        pageSize: this.pageSize,
      });
      this.bannerList = res.data.records;
      this.total = res.data.total;
    },
    // 分页
    handleCurrentChange(page) {
      this.page = page;
      this.getBannerList();
    },
    // 删除轮播图
    delBanner(banner) {
      MessageBox.confirm("你确定要删除该轮播图吗？", "提示", {
        type: "warning",
        confirmButtonText: "确认",
        cancelButtonText: "取消",
      })
        .then(async () => {
          try {
            this.loading = true;
            await delBanner({
              id: banner.id,
              url: banner.url,
            });
            this.getBannerList();
          } finally {
            this.loading = false;
          }
        })
        .catch(() => {});
    },
    // 切换状态
    async toggleStatus(id, status) {
      status = status === 0 ? 1 : 0;
      await updateStatus({ id, status });
      this.getBannerList();
    },
    // 获取文件
    dropFiles(e) {
      // 阻止默认行为，防止文件在浏览器中被打开
      e.preventDefault();
      const files = e.dataTransfer.files;
      Object.keys(files).forEach((key) => {
        const flag = this.checkFile(files[key]);
        if (flag) {
          this.handleFile(files[key]);
        }
      });
    },
    // 移除文件
    removeFile(index) {
      this.fileList.splice(index, 1);
    },
    // 文件拖拽到指定区域后触发（连续）
    allowDrop(e) {
      // 阻止默认行为，防止文件在浏览器中被打开
      e.preventDefault();
    },
    // 获取文件
    handleFileChange(el) {
      const fileList = el.target.files;
      Object.keys(fileList).forEach((key) => {
        const flag = this.checkFile(fileList[key]);
        if (flag) {
          this.handleFile(fileList[key]);
        }
      });
    },
    //处理文件
    handleFile(file) {
      const newIndex = this.fileList.length;
      this.fileList.push(file);
      let reader = new FileReader();
      reader.readAsDataURL(file);
      // 当FileReader完成文件读取的时候会触发该事件（例如reader.onload）
      reader.onload = () => {
        // vue无法检测数组变化导致视图不会及时更新，使用this.$set()方法强制更新
        this.$set(this.fileList, newIndex, {
          file: file,
          url: reader.result,
        });
      };
    },
    // 判断文件是否符合要求
    checkFile(file) {
      const fileType =
        file.type === "image/png" ||
        file.type === "image/jpeg" ||
        file.type === "image/gif";
      const fileSize = file.size / 1024 / 1024 < 2;
      if (!fileType) {
        this.$message.error("请上传png或jpg或gif格式的图片");
        return false;
      }
      if (!fileSize) {
        this.$message.error("图片大小不能超过2MB");
        return false;
      }
      return fileType && fileSize;
    },
    // 上传文件
    async upload() {
      const formData = new FormData();
      this.fileList.forEach((item) => {
        formData.append("file", item.file);
      });
      try {
        this.isUpload = true;
        const res = await uploadFiles(formData);
        this.fileList = [];
        await addBanner(res.data);
        this.getBannerList();
      } finally {
        this.isUpload = false;
        this.showAddBanner = false;
      }
    },
  },
};
</script>

<style lang="less" scoped>
.banner {
  margin-top: 20px;
  padding: 10px;
  .btn {
    padding: 10px 20px;
    border-radius: 30px;
    border: none;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.3s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
  }
  .action-bar {
    margin-bottom: 30px;
    padding-bottom: 20px;
    border-bottom: 1px solid #e5e7eb;
    .btn-rainbow {
      background: linear-gradient(
        90deg,
        #ff4757 0%,
        #ffa502 25%,
        #2ed573 50%,
        #4a6cf7 75%,
        #9c51b6 100%
      );
      background-size: 200% auto;
      color: white;
      font-weight: 600;
      &:hover {
        background-position: right center;
        animation: rainbowGlow 1.5s infinite alternate;
      }
      @keyframes rainbowGlow {
        from {
          box-shadow: 0 0 10px rgba(255, 71, 87, 0.7);
        }
        to {
          box-shadow: 0 0 20px rgba(156, 81, 182, 0.7);
        }
      }
    }
  }
  .carousel-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
    margin-top: 20px;
    .carousel-card {
      background: white;
      border-radius: 12px;
      /* overflow: hidden; */
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
      transition: all 0.3s ease;
      &:hover {
        transform: perspective(1000px) rotateY(5deg);
        box-shadow: 0 8px 30px rgba(74, 108, 247, 0.2);
      }
      .carousel-image {
        height: 160px;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        border-top-left-radius: inherit;
        border-top-right-radius: inherit;
      }
      .carousel-content {
        display: flex;
        justify-content: space-between;
        padding: 15px;
        .btn-danger {
          width: 46%;
          background: #fa5765;
          color: white;
          &:hover {
            background: #ff1f4b;
          }
        }
        .btn-success {
          width: 46%;
          background: #2ed573;
          color: white;
        }
        .btn-disabled {
          width: 46%;
          background: #ffa502;
          color: white;
        }
      }
    }
  }
  .file-tool {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin: 0 auto;
    width: 280px;
    height: 140px;
    border: 1px dashed #ccc;
    border-radius: 10px;
    cursor: pointer;
    i {
      font-size: 50px;
      color: rgb(192, 196, 204);
    }
  }
  .file-container {
    margin-top: 20px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 20px;
    .item {
      position: relative;
      width: 200px;
      height: 120px;
      border: 1px solid rgb(192, 204, 218);
      border-radius: 10px;
      &:hover {
        .success {
          display: none;
        }
        .error {
          display: block;
        }
      }
      img {
        width: 100%;
        height: 100%;
        border-radius: inherit;
      }
      span {
        position: absolute;
        top: 0;
        right: 0;
        font-size: 20px;
        border-top-right-radius: 10px;
        cursor: pointer;
      }
      .success {
        display: block;
      }
      .error {
        display: none;
      }
    }
  }
}
</style>